package cn.ichiva.common.kv.impl;


import cn.ichiva.common.kv.KVDB;
import cn.ichiva.common.kv.KVException;

import cn.ichiva.common.io.*;

import java.io.*;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * Created by game group on 2020/12/3.
 */
public class KVDBImpl implements KVDB {

    private final File rootDir;

    public KVDBImpl(File rootDir){
        this.rootDir = rootDir;

        if(!rootDir.exists()){
            rootDir.mkdirs();
        }
    }

    @Override
    public byte[] put(String key, byte[] val) {
        if(key == null || key .length() == 0){
            throw new NullPointerException("key 不能为null或空");
        }

        if (key.length() > 250) {
            throw new KVException("键太长,最长不能超过250");
        }

        synchronized (key.intern()){
            File file = new File(rootDir, key);
            byte[] res = null;
            if(file.exists()){
                try {
                    res = IOHelper.read(file);
                } catch (IOException e) {
                    throw  new KVException(e);
                }
            }

            try {
                IOHelper.write(file,val);
            } catch (IOException e) {
                throw  new KVException(e);
            }

            return res;
        }
    }

    public byte[] put(String key, String val) {
        try {
           return put(key,val.getBytes("utf-8"));
        } catch (UnsupportedEncodingException e) {
            throw new KVException(e);
        }
    }

        @Override
    public byte[] get(String key) {
        if(key == null || key .length() == 0){
            throw new NullPointerException("key 不能为null或空");
        }

        if (key.length() > 250) {
            throw new KVException("键太长,最长不能超过250");
        }

        File file = new File(rootDir, key);
        if(!file.exists()) return null;

        synchronized (key.intern()) {
            try {
                return IOHelper.read(file);
            } catch (IOException e) {
                throw new KVException(e);
            }
        }
    }

    @Override
    public byte[] remove(String key) {
        File file = new File(rootDir, key);
        byte[] res = get(key);
        file.delete();
        return res;
    }

    public String getString(String key) {
        try {
            return new String(get(key),"utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new KVException(e);
        }
    }

    @Override
    public Set<String> keys() {
        return FilesPlus.allFiles(rootDir).stream().map(File::getName).collect(Collectors.toSet());
    }

    @Override
    public Set<String> keys(String regex) {
        Pattern p = Pattern.compile(regex);
        return keys().stream().filter(e -> p.matcher(e).matches()).collect(Collectors.toSet());
    }
}
